package com.talent.service.iot.mqtt.handler;

import com.talent.service.iot.mqtt.config.Constant;
import com.talent.service.iot.mqtt.model.request.TlMqttPubRecReq;
import com.talent.service.iot.mqtt.model.request.TlMqttPubRelReq;
import com.talent.service.iot.mqtt.model.variable.TlMqttPubRecVariableHead;
import com.talent.service.iot.mqtt.service.IMqttMsgService;
import com.talent.service.iot.mqtt.service.IMqttSessionService;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Set;


/**
 * @Author: hszhou
 * @Date: 2024/12/5 9:46
 * @Description: 必须描述类做什么事情, 实现什么功能
 */
@ChannelHandler.Sharable
@Component
public class TlMqttPubRecHandler extends SimpleChannelInboundHandler<TlMqttPubRecReq> {

    private static final Logger logger = LoggerFactory.getLogger(TlMqttPubRecHandler.class);

    private final IMqttSessionService sessionService;

    private final IMqttMsgService msgService;

    public TlMqttPubRecHandler(IMqttSessionService sessionService,IMqttMsgService msgService){
        this.sessionService = sessionService;
        this.msgService = msgService;
    }
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TlMqttPubRecReq req) throws Exception {
        logger.debug("in【PUBREC】 handler");
        String clientId = ctx.channel().attr(AttributeKey.valueOf(Constant.CLIENT_ID)).get().toString();
        TlMqttPubRecVariableHead vh = req.getVariableHead();
        Integer messageId = vh.getMessageId();

        //收到rec的消息 说明接受方已经收到了发送放的publish消息了 可以吧这个publish消息删除了 并且删除session中的pub消息
        msgService.clearPublishMessage(clientId,messageId);
        logger.debug("【CLIENT】 2. 【{}】 remove pub messageId【{}】",clientId,messageId);
        //清除session中的pub消息
        sessionService.find(clientId).subscribe(session->{
            Set<Integer> publishMsgStore = session.getPublishMsgStore();
            publishMsgStore.remove(messageId);
            logger.debug("client 【{}】 session remove messageId is 【{}】",clientId,messageId);
        });

        //发送REL消息 告诉发送方 可以发送COMP消息了
        TlMqttPubRelReq res = TlMqttPubRelReq.of(messageId);

        //保存rec的消息
        msgService.savePubRecMessage(clientId,messageId,req);
        logger.debug("【CLIENT】 3. 【{}】 save pubrec message 【{}】",clientId,messageId);
        ctx.channel().writeAndFlush(res);
        logger.debug("client【{}】 build 【PUBREL】",clientId);

    }
}
